package com.bdqn.bookshop.controller.common;

import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpSession;

import com.bdqn.bookshop.common.BookConstants;
import com.bdqn.bookshop.entity.Books;
import com.bdqn.bookshop.entity.MallUser;
import com.bdqn.bookshop.service.BooksService;
import com.bdqn.bookshop.utils.Result;
import org.apache.commons.codec.binary.Base64;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
/**
 * @author : 罗若然[LUO_RUO_RAN]
 * @date : 2020-07-25 10:05
 **/
@Controller
@RequestMapping("/")
public class QrcodeController {

    private Map<String, Object> loginMap = new ConcurrentHashMap<>();


    @Autowired
    private BooksService booksService;
    /**
     * 获取二维码
     *
     * @return
     */
    @GetMapping("/mall/getQrCode/{id}")
    public @ResponseBody Map<String, Object> getQrCode(@PathVariable("id") Integer id) throws Exception {
        Map<String, Object> result = new HashMap<>();
        String uuid = UUID.randomUUID().toString().replace("-", "").toUpperCase();
        result.put("mallId", uuid);

        // app端支付地址
        String payUrl = "http://luoruoran.qicp.vip/mall/payUrl/"+uuid+"/"+id;
        result.put("payUrl", payUrl);
        result.put("image", createQrCode(payUrl));
        return result;
    }

    /**
     * app二维码支付地址
     *
     * @param mallId
     * @param id
     * @return
     */
    @GetMapping("/mall/payUrl/{mallId}/{id}")
    public @ResponseBody Map<String, Object> setUser(@PathVariable String mallId, @PathVariable Integer id,HttpSession session) {
        Map<String, Object> result = new HashMap<>();
        if (loginMap.containsKey(mallId)) {
            Books books = new Books();
            MallUser mallUser = (MallUser) session.getAttribute(BookConstants.LOGIN_MALL_USER);
            books.setPurchaser(mallUser.getId());
            books.setId(Integer.valueOf(id));
            books.setState(2);
            Boolean result1 = (Boolean) loginMap.get("result");
            result1 = booksService.updateBookState(books).isSuccess();

            // 唤醒支付等待线程
            CountDownLatch l = (CountDownLatch) loginMap.get(mallId);
            l.countDown();
            result.put("mallId", mallId);
        }


        result.put("id", id);
        return result;
    }

    /**
     * 等待二维码扫码结果的长连接
     *
     * @param mallId
     * @param session
     * @return
     */
    @GetMapping("/mall/getResponse/{mallId}/{id}")
    public @ResponseBody Map<String, Object> getResponse(@PathVariable String mallId, HttpSession session,@PathVariable("id") String id) {
        CountDownLatch latch = null;
        Boolean result1 = false;
        Map<String, Object> result = new HashMap<>();
        result.put("mallId", mallId);

        try {
            if (latch == null) {
                latch = new CountDownLatch(1);
                loginMap.put(mallId, latch);
                loginMap.put("result",result1);
            }
            try {
                // 线程等待
                latch.await(1, TimeUnit.MINUTES);
            } catch (Exception e) {
                e.printStackTrace();
            }

            // 再次判断
            if ( result1) {
                //session.setAttribute(WebSecurityConfig.SESSION_KEY, loginResponse.user);
                result.put("success", true);
                return result;
            }

            result.put("success", false);
            return result;
        } finally {
            // 移除支付请求
            if (loginMap.containsKey(mallId)) {
                loginMap.remove(mallId);
                loginMap.remove("result");
            }

        }
    }

    /**
     * 生成base64二维码
     *
     * @param content
     * @return
     * @throws Exception
     */
        private String createQrCode(String content) throws Exception {
        try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
            Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();
            hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
            hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
            hints.put(EncodeHintType.MARGIN, 1);
            BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, 400, 400, hints);
            int width = bitMatrix.getWidth();
            int height = bitMatrix.getHeight();
            BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
            for (int x = 0; x < width; x++) {
                for (int y = 0; y < height; y++) {
                    image.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF);
                }
            }
            ImageIO.write(image, "JPG", out);
            return Base64.encodeBase64String(out.toByteArray());
        }
    }

}
